﻿using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using UpperComputer.Application;
using UpperComputer.WPF.Entry.Common;
using UpperComputer.WPF.Entry.Common.Extensions;
using UpperComputer.WPF.Entry.Views;
using YFurion.Application;

namespace UpperComputer.WPF.Entry.ViewModels
{
    public class MenuViewModel : ManagementViewModel
    {
        private readonly IBaseMenuService _menuService;

        private BaseMenuResultDto _currentMenu;

        public IRelayCommand<BaseMenuResultDto> SelectTreeViewItemCommand { get; }

        private PagedResultDto<BaseMenuResultDto> _menuPaged = new();
        public PagedResultDto<BaseMenuResultDto> MenuPaged
        {
            get => _menuPaged;
            set => SetProperty(ref _menuPaged, value);
        }

        public MenuViewModel(IBaseMenuService menuService)
        {
            _menuService = menuService;
            SelectTreeViewItemCommand = new RelayCommand<BaseMenuResultDto>(SelectTreeViewItem);
        }

        protected override async Task LoadAsync(object parameter, CancellationToken cancellationToken)
        {
            await PageMenuDataAsync(cancellationToken);
        }

        /// <summary>
        /// 获取菜单数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private async Task PageMenuDataAsync(CancellationToken cancellationToken, BaseMenuResultRequestDto input = null)
        {
            input ??= new BaseMenuResultRequestDto();
            input.MaxResultCount = int.MaxValue;
            PagedResultDto<BaseMenuResultDto> menuPaged = await _menuService.GetAll(input, cancellationToken);

            List<BaseMenuResultDto> baseMenus = new();
            RecursionMenu(menuPaged.Items, string.Empty, baseMenus);

            menuPaged.Items = baseMenus;
            MenuPaged = menuPaged;
        }

        /// <summary>
        /// 递归获取数据
        /// </summary>
        /// <param name="input"></param>
        /// <param name="parentCode"></param>
        /// <param name="childrens"></param>
        private void RecursionMenu(IReadOnlyList<BaseMenuResultDto> input, string parentCode, ICollection<BaseMenuResultDto> childrens)
        {
            //判断是否存在子级菜单
            bool exist = input.Any(p => p.ParentCode == parentCode);
            if (!exist)
            {
                return;
            }

            for (int i = 0; i < input.Count; i++)
            {
                BaseMenuResultDto item = input[i];
                if (item.ParentCode != parentCode)
                {
                    continue;
                }

                RecursionMenu(input, item.Code, item.Childrens); //如果条件符合，执行递归
                childrens.Add(item); //加载进父级当中
            }
        }

        protected override async Task PostAsync(CancellationToken cancellationToken)
        {
            MenuOperationControl menuOperationControl = Furion.App.GetService<MenuOperationControl>();
            object result = await ShowRootDialog(menuOperationControl);
            if (result != null)
            {
                await LoadAsync(1, cancellationToken);
            }
        }

        protected override async Task PutAsync(CancellationToken cancellationToken)
        {
            if (_currentMenu == null)
            {
                Snackbar.ShowWarningMessage("请选择一行编辑");
                return;
            }
            MenuOperationControl menuOperationControl = Native.CreateInstance<MenuOperationControl>(_currentMenu.Id);
            object result = await ShowRootDialog(menuOperationControl);
            if (result != null)
            {
                await LoadAsync(null, cancellationToken);
            }
        }

        protected override async Task DeleteAsync(CancellationToken cancellationToken)
        {
            if (_currentMenu == null)
            {
                Snackbar.ShowWarningMessage("请选择一行删除");
                return;
            }
            MessageBoxResult mbr = this.ShowQuestionBox("确定要删除吗");
            if (mbr == MessageBoxResult.OK)
            {
                await _menuService.Delete(_currentMenu.Id, cancellationToken);
                await PageMenuDataAsync(cancellationToken);
            }
        }

        public void SelectTreeViewItem(BaseMenuResultDto item)
        {
            _currentMenu = item;
        }
    }
}
